﻿using SuperMap.Analyst.NetworkAnalyst;
using SuperMap.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MDF
{
    class MatchTopology
    {
        private Datasource m_datasource;
        /// <summary>
        /// 拓扑匹配初始化
        /// </summary>
        /// <param name="datasource">保存中间数据的数据集</param>
        public MatchTopology(Datasource datasource) 
        {
            m_datasource = datasource;
            //统计进度
            DatasetsMatchResult.TopollogyProgressCount = 0;
            DatasetsMatchResult.TopollogyProgressValue = 0;
        }
        /// <summary>
        /// 拓扑匹配初始化
        /// </summary>
        /// <param name="datasource">保存中间数据的数据集</param>
        /// <param name="IsStart">是否初始化进度</param>
        public MatchTopology(Datasource datasource,bool IsStart)
        {
            m_datasource = datasource;
            if (IsStart)
            {
                //统计进度
                DatasetsMatchResult.TopollogyProgressCount = 0;
                DatasetsMatchResult.TopollogyProgressValue = 0;
            }
        }
        /// <summary>
        /// 点要素拓扑匹配
        /// </summary>
        /// <param name="point1">点记录集1</param>
        /// <param name="line1Vs">与点记录集1关联的线矢量集集合</param>
        /// <param name="point2">点记录集2</param>
        /// <param name="line2Vs">与点记录集2关联的线矢量集集合</param>
        /// <param name="ToleranceTh">节点容限，单位m</param>
        /// <param name="DepthTh">拓扑检索深度</param>
        /// <param name="topologyError">拓扑匹配结果保留阈值</param>
        /// <returns>返回线拓扑匹配的结果列表，其单个元素形式为double[] { geoLine1.ID, geoLine2.ID, Sim }</returns>
        public List<double[]> MatchDataPoint(Recordset point1, DatasetVector[] line1Vs, Recordset point2, DatasetVector[] line2Vs, double topologyError, double ToleranceTh, int DepthTh)
        {
            try
            {
                //记录匹配信息
                List<double[]> SimPoints = new List<double[]>();
                //获取矢量数据集
                DatasetVector[] point1Vs = new DatasetVector[] { point1.Dataset };
                DatasetVector[] point2Vs = new DatasetVector[] { point2.Dataset };
                //获取网络数据集(并行处理两个网络集)
                Task<DatasetVector> task1 = new Task<DatasetVector>(() => BuildNetwork(line1Vs, point1Vs, "NetworkDataset_1", ToleranceTh));
                Task<DatasetVector> task2 = new Task<DatasetVector>(() => BuildNetwork(line2Vs, point2Vs, "NetworkDataset_2", ToleranceTh));
                task2.Start();
                task1.Start();
                //当两个任务都完成后，进行下一步匹配
                if (Task.WaitAll(new Task[] { task1, task2 }, -1))
                {
                    //获取网络集
                    DatasetVector line1Net = task1.Result;
                    DatasetVector line2Net = task2.Result;
                    //遍历数据
                    point1.MoveFirst();
                    for (int i = 0; i < point1.RecordCount; i++)
                    {
                        //获取点对像1
                        Geometry geoPoint1 = point1.GetGeometry();
                        //获取点对象所在的线对象
                        Geometry geoLine1 = GetPointInLine(geoPoint1, line1Vs);
                        if(geoLine1 != null)
                        {
                            //获取每层几何对象集
                            List<Geometry[]> geometries1 = GetGeoData(geoLine1, line1Vs, DepthTh);
                            //获取每层AaC值的集合
                            List<int[]> AaC1 = GetAaCinfo(geometries1, line1Net);
                            point2.MoveFirst();
                            for (int j = 0; j < point2.RecordCount; j++)
                            {
                                //获取点对像1
                                Geometry geoPoint2 = point2.GetGeometry();
                                //获取点对象所在的线对象
                                Geometry geoLine2 = GetPointInLine(geoPoint2, line2Vs);
                                if (geoLine2 != null)
                                {
                                    //获取每层几何对象集
                                    List<Geometry[]> geometries2 = GetGeoData(geoLine2, line2Vs, DepthTh);
                                    //获取每层AaC值的集合
                                    List<int[]> AaC2 = GetAaCinfo(geometries2, line2Net);
                                    //获取本身对应弧段节点情况并判断是否计算相似度
                                    double check1 = Math.Abs(AaC1[0][0] - AaC2[0][0]);
                                    double check2 = Math.Abs(AaC1[0][0] - AaC2[0][0]) / Math.Max(AaC1[0][0], AaC2[0][0]);
                                    //判断比例是否在可计算范围内（实际上给出的限制比较宽松）
                                    if (check1 <= 3 && check2 <= 0.5)
                                    {
                                        //在范围内才计算相似度（仅保留符合阈值的相似度的值）
                                        double sim = GetSim(AaC1, AaC2, topologyError);
                                        if (sim >= topologyError)
                                        {
                                            //记录结果信息
                                            SimPoints.Add(new double[] { geoLine1.ID, geoLine2.ID, sim });
                                        }
                                    } 
                                }
                                else
                                {
                                    //没有对象则跳过本次循环
                                    continue;
                                }
                                //释放局部资源
                                geoPoint2.Dispose();
                                geoLine2.Dispose();
                                //移动记录
                                point2.MoveNext();
                            }
                        }
                        else
                        {
                            //没有对象则跳过本次循环，记录id
                            SimPoints.Add(new double[] { geoPoint1.ID, 0, 0 });
                            continue;
                        }
                        //释放局部资源
                        geoPoint1.Dispose();
                        geoLine1.Dispose();
                        //移动记录
                        point1.MoveNext();
                    }
                    //删除临时网络数据集
                    m_datasource.Datasets.Delete(line1Net.Name);
                    m_datasource.Datasets.Delete(line2Net.Name);
                }
                //返回结果
                return SimPoints;
            }
            catch (Exception)
            {

                throw;
            }
        }
        /// <summary>
        /// 点要素拓扑匹配
        /// </summary>
        /// <param name="point1">点记录集1</param>
        /// <param name="line1Vs">与点记录集1关联的线矢量集集合</param>
        /// <param name="point2">点记录集2</param>
        /// <param name="line2Vs">与点记录集2关联的线矢量集集合</param>
        /// <param name="ToleranceTh">节点容限，单位m</param>
        /// <param name="DepthTh">拓扑检索深度</param>
        /// <param name="topologyError">拓扑匹配结果保留阈值</param>
        /// <param name="Token">取消操作的对象</param>
        /// <returns>返回线拓扑匹配的结果列表，其单个元素形式为double[] { geoLine1.ID, geoLine2.ID, Sim }</returns>
        public List<double[]> MatchDataPoint(Recordset point1, DatasetVector[] line1Vs, Recordset point2, DatasetVector[] line2Vs, double topologyError, double ToleranceTh, int DepthTh, CancellationToken Token)
        {
            try
            {
                
                //获取矢量数据集
                DatasetVector[] point1Vs = new DatasetVector[] { point1.Dataset };
                DatasetVector[] point2Vs = new DatasetVector[] { point2.Dataset };
                //获取网络数据集(并行处理两个网络集)
                Task<DatasetVector> task1 = new Task<DatasetVector>(() => BuildNetwork(line1Vs, point1Vs, "NetworkDataset_1", ToleranceTh, Token), Token);
                Task<DatasetVector> task2 = new Task<DatasetVector>(() => BuildNetwork(line2Vs, point2Vs, "NetworkDataset_2", ToleranceTh, Token), Token);
                task2.Start();
                task1.Start();
                //当两个任务都完成后，进行下一步匹配
                if (Task.WaitAll(new Task[] { task1, task2 }, -1) && !Token.IsCancellationRequested)
                {
                    //记录匹配信息
                    List<double[]> SimPoints = new List<double[]>();
                    //获取网络集
                    DatasetVector line1Net = task1.Result;
                    DatasetVector line2Net = task2.Result;
                    //遍历数据
                    point1.MoveFirst();
                    for (int i = 0; i < point1.RecordCount; i++)
                    {
                        //获取点对像1
                        Geometry geoPoint1 = point1.GetGeometry();
                        //获取点对象所在的线对象
                        Geometry geoLine1 = GetPointInLine(geoPoint1, line1Vs);
                        if (geoLine1 != null)
                        {
                            //获取每层几何对象集
                            List<Geometry[]> geometries1 = GetGeoData(geoLine1, line1Vs, DepthTh);
                            //获取每层AaC值的集合
                            List<int[]> AaC1 = GetAaCinfo(geometries1, line1Net);
                            point2.MoveFirst();
                            for (int j = 0; j < point2.RecordCount; j++)
                            {
                                if (Token.IsCancellationRequested)
                                {
                                    //释放局部资源
                                    geoPoint1.Dispose();
                                    geoLine1.Dispose();
                                    //删除临时网络数据集
                                    m_datasource.Datasets.Delete(line1Net.Name);
                                    m_datasource.Datasets.Delete(line2Net.Name);
                                    return null;
                                }
                                else
                                {
                                    //获取点对像2
                                    Geometry geoPoint2 = point2.GetGeometry();
                                    //获取点对象所在的线对象
                                    Geometry geoLine2 = GetPointInLine(geoPoint2, line2Vs);
                                    if (geoLine2 != null)
                                    {
                                        //获取每层几何对象集
                                        List<Geometry[]> geometries2 = GetGeoData(geoLine2, line2Vs, DepthTh);
                                        //获取每层AaC值的集合
                                        List<int[]> AaC2 = GetAaCinfo(geometries2, line2Net);
                                        //获取本身对应弧段节点情况并判断是否计算相似度
                                        double check1 = Math.Abs(AaC1[0][0] - AaC2[0][0]);
                                        double check2 = Math.Abs(AaC1[0][0] - AaC2[0][0]) / Math.Max(AaC1[0][0], AaC2[0][0]);
                                        //判断比例是否在可计算范围内（实际上给出的限制比较宽松）
                                        if (check1 <= 3 && check2 <= 0.5)
                                        {
                                            //在范围内才计算相似度（仅保留符合阈值的相似度的值）
                                            double sim = GetSim(AaC1, AaC2, topologyError);
                                            if (sim >= topologyError)
                                            {
                                                //记录结果信息
                                                SimPoints.Add(new double[] { geoLine1.ID, geoLine2.ID, sim });
                                            }
                                        }
                                    }
                                    else
                                    {
                                        //没有对象则跳过本次循环
                                        continue;
                                    }
                                    //释放局部资源
                                    geoPoint2.Dispose();
                                    geoLine2.Dispose();
                                    //移动记录
                                    point2.MoveNext();
                                    //记录进度
                                    DatasetsMatchResult.TopollogyProgressCount++;
                                    DatasetsMatchResult.TopollogyProgressValue = DatasetsMatchResult.TopollogyProgressCount * 100 / DatasetsMatchResult.SetsRecordCountSum;
                                }
                            }
                        }
                        else
                        {
                            //没有对象则跳过本次循环，记录id
                            SimPoints.Add(new double[] { geoPoint1.ID, 0, 0 });
                            //记录进度
                            DatasetsMatchResult.TopollogyProgressCount += point2.RecordCount;
                            DatasetsMatchResult.TopollogyProgressValue = DatasetsMatchResult.TopollogyProgressCount * 100 / DatasetsMatchResult.SetsRecordCountSum;
                            continue;
                        }
                        //释放局部资源
                        geoPoint1.Dispose();
                        geoLine1.Dispose();
                        //移动记录
                        point1.MoveNext();
                    }
                    //删除临时网络数据集
                    m_datasource.Datasets.Delete(line1Net.Name);
                    m_datasource.Datasets.Delete(line2Net.Name);
                    //返回结果
                    return SimPoints;
                }
                else
                {
                    //返回结果
                    return null;
                }
                
            }
            catch (Exception)
            {

                throw;
            }
        }
        /// <summary>
        /// 获取点所在的线对象，如有多个线对线，则值返回查询结果中的第一个
        /// </summary>
        /// <param name="geoPoint">点对象</param>
        /// <param name="datasets">线数据集合</param>
        /// <returns>线对像</returns>
        private Geometry GetPointInLine(Geometry geoPoint, DatasetVector[] datasets)
        {
            try
            {
                //记录要返回的查询对象
                Geometry geometry = null;
                //实例查询参数（查询对象(循环内添加)、查询算子、静态游标）
                QueryParameter queryParameter = new QueryParameter()
                {
                    SpatialQueryObject = geoPoint,
                    SpatialQueryMode = SpatialQueryMode.Within,
                    CursorType = CursorType.Static
                };
                for (int i = 0; i < datasets.Length; i++)
                {
                    //查询得到记录集
                    Recordset recordset = datasets[i].Query(queryParameter);
                    if (recordset != null)
                    {
                        recordset.MoveFirst();
                        //获取线对象
                        geometry = recordset.GetGeometry();
                        //释放局部资源，跳出
                        recordset.Dispose();
                        break;
                    }
                }
                if (geometry != null)
                {
                    return geometry;
                }
                else
                {
                    return null;
                }
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 线要素拓扑匹配
        /// </summary>
        /// <param name="line1">线记录集1</param>
        /// <param name="line2">线记录集2</param>
        /// <param name="ToleranceTh">节点容限，单位m</param>
        /// <param name="DepthTh">拓扑检索深度</param>
        /// <param name="topologyError">拓扑匹配结果保留阈值</param>
        /// <returns>返回线拓扑匹配的结果列表，其单个元素形式为double[] { geoLine1.ID, geoLine2.ID, Sim }</returns>
        public List<double[]> MatchDataLine(Recordset line1, Recordset line2, double topologyError, double ToleranceTh, int DepthTh)
        {
            try
            {
                //记录匹配信息
                List<double[]> SimLines = new List<double[]>();
                //获取矢量数据集集合
                DatasetVector[] line1Vs = new DatasetVector[] { line1.Dataset };
                DatasetVector[] line2Vs = new DatasetVector[] { line2.Dataset };
                //获取网络数据集(并行处理两个网络集)
                Task<DatasetVector> task1 = new Task<DatasetVector>(() => BuildNetwork(line1Vs, new DatasetVector[] { }, "NetworkDataset_1", ToleranceTh));
                Task<DatasetVector> task2 = new Task<DatasetVector>(() => BuildNetwork(line2Vs, new DatasetVector[] { }, "NetworkDataset_2", ToleranceTh));
                task2.Start();
                task1.Start();
                //当两个任务都完成后，进行下一步匹配
                if (Task.WaitAll(new Task[] { task1, task2 }, -1))
                {
                    //获取网络集
                    DatasetVector line1Net = task1.Result;
                    DatasetVector line2Net = task2.Result;
                    //遍历数据
                    line1.MoveFirst();
                    for (int i = 0; i < line1.RecordCount; i++)
                    {
                        //获取线对像1
                        Geometry geoLine1 = line1.GetGeometry();
                        //获取每层几何对象集
                        List<Geometry[]> geometries1 = GetGeoData(geoLine1, line1Vs, DepthTh);
                        //获取每层AaC值的集合
                        List<int[]> AaC1 = GetAaCinfo(geometries1, line1Net);
                        line2.MoveFirst();
                        for (int j = 0; j < line2.RecordCount; j++)
                        {
                            //获取线对像2
                            Geometry geoLine2 = line2.GetGeometry();
                            //获取每层几何对象集
                            List<Geometry[]> geometries2 = GetGeoData(geoLine2, line2Vs, DepthTh);
                            //获取每层AaC值的集合
                            List<int[]> AaC2 = GetAaCinfo(geometries2, line2Net);
                            //获取本身对应弧段节点情况并判断是否计算相似度
                            double check1 = Math.Abs(AaC1[0][0] - AaC2[0][0]);
                            double check2 = Math.Abs(AaC1[0][0] - AaC2[0][0]) / Math.Max(AaC1[0][0], AaC2[0][0]);
                            //判断比例是否在可计算范围内（实际上给出的限制比较宽松）
                            if (check1 <= 3 && check2 <= 0.5)
                            {
                                //在范围内才计算相似度（仅保留符合阈值的相似度的值）
                                double sim = GetSim(AaC1, AaC2, topologyError);
                                if (sim >= topologyError)
                                {
                                    //记录结果信息
                                    SimLines.Add(new double[] { geoLine1.ID, geoLine2.ID, sim });
                                }
                            }
                            //释放局部资源
                            geoLine2.Dispose();
                            //移动记录
                            line2.MoveNext();
                        }
                        //释放局部资源
                        geoLine1.Dispose();
                        //移动记录
                        line1.MoveNext();
                    }
                    //删除临时网络数据集
                    m_datasource.Datasets.Delete(line1Net.Name);
                    m_datasource.Datasets.Delete(line2Net.Name);
                }
                //返回结果
                return SimLines;
            }
            catch (Exception)
            {

                throw;
            }
        }
        /// <summary>
        /// 线要素拓扑匹配
        /// </summary>
        /// <param name="line1">线记录集1</param>
        /// <param name="line2">线记录集2</param>
        /// <param name="ToleranceTh">节点容限，单位m</param>
        /// <param name="DepthTh">拓扑检索深度</param>
        /// <param name="topologyError">拓扑匹配结果保留阈值</param>
        /// <param name="Token">取消操作的对象</param>
        /// <returns>返回线拓扑匹配的结果列表，其单个元素形式为double[] { geoLine1.ID, geoLine2.ID, Sim }</returns>
        public List<double[]> MatchDataLine(Recordset line1, Recordset line2, double topologyError, double ToleranceTh, int DepthTh, CancellationToken Token)
        {
            try
            {
                
                //获取矢量数据集集合
                DatasetVector[] line1Vs = new DatasetVector[] { line1.Dataset };
                DatasetVector[] line2Vs = new DatasetVector[] { line2.Dataset };
                //获取网络数据集(并行处理两个网络集)
                Task <DatasetVector> task1 = new Task<DatasetVector>(() => BuildNetwork(line1Vs, new DatasetVector[] { }, "NetworkDataset_1", ToleranceTh, Token), Token);
                Task<DatasetVector> task2 = new Task<DatasetVector>(() => BuildNetwork(line2Vs, new DatasetVector[] { }, "NetworkDataset_2", ToleranceTh, Token), Token);
                task1.Start();
                task2.Start();
                //当两个任务都完成后，进行下一步匹配
                if (Task.WaitAll(new Task[] { task1, task2 }, -1) && !Token.IsCancellationRequested)
                {
                    //记录匹配信息
                    List<double[]> SimLines = new List<double[]>();
                    //获取网络集
                    DatasetVector line1Net = task1.Result;
                    DatasetVector line2Net = task2.Result;
                    //遍历数据
                    line1.MoveFirst();
                    for (int i = 0; i < line1.RecordCount; i++)
                    {
                        //获取线对像1
                        Geometry geoLine1 = line1.GetGeometry();
                        //获取每层几何对象集
                        List<Geometry[]> geometries1 = GetGeoData(geoLine1, line1Vs, DepthTh);
                        //获取每层AaC值的集合
                        List<int[]> AaC1 = GetAaCinfo(geometries1, line1Net);
                        line2.MoveFirst();
                        for (int j = 0; j < line2.RecordCount; j++)
                        {
                            if (Token.IsCancellationRequested)
                            {
                                //释放局部资源
                                geoLine1.Dispose();
                                //删除临时网络数据集
                                m_datasource.Datasets.Delete(line1Net.Name);
                                m_datasource.Datasets.Delete(line2Net.Name);
                                return null;
                            }
                            else
                            {
                                //获取线对像2
                                Geometry geoLine2 = line2.GetGeometry();
                                //获取每层几何对象集
                                List<Geometry[]> geometries2 = GetGeoData(geoLine2, line2Vs, DepthTh);
                                //获取每层AaC值的集合
                                List<int[]> AaC2 = GetAaCinfo(geometries2, line2Net);
                                //获取本身对应弧段节点情况并判断是否计算相似度
                                double check1 = Math.Abs(AaC1[0][0] - AaC2[0][0]);
                                double check2 = Math.Abs(AaC1[0][0] - AaC2[0][0]) / Math.Max(AaC1[0][0], AaC2[0][0]);
                                //判断比例是否在可计算范围内（实际上给出的限制比较宽松）
                                if (check1 <= 3 && check2 <= 0.5)
                                {
                                    //在范围内才计算相似度（仅保留符合阈值的相似度的值）
                                    double sim = GetSim(AaC1, AaC2, topologyError);
                                    if (sim >= topologyError)
                                    {
                                        //记录结果信息
                                        SimLines.Add(new double[] { geoLine1.ID, geoLine2.ID, sim });
                                    }
                                }
                                //释放局部资源
                                geoLine2.Dispose();
                                //移动记录
                                line2.MoveNext();
                                //记录进度
                                DatasetsMatchResult.TopollogyProgressCount++;
                                DatasetsMatchResult.TopollogyProgressValue = DatasetsMatchResult.TopollogyProgressCount * 100 / DatasetsMatchResult.SetsRecordCountSum;
                            }
                        }
                        //释放局部资源
                        geoLine1.Dispose();
                        //移动记录
                        line1.MoveNext();
                    }
                    //删除临时网络数据集
                    m_datasource.Datasets.Delete(line1Net.Name);
                    m_datasource.Datasets.Delete(line2Net.Name);
                    //返回结果
                    return SimLines;
                }
                else
                {
                    //返回结果
                    return null;
                }
                
            }
            catch (Exception)
            {

                throw;
            }
        }
        /// <summary>
        /// 构建网络，添加节点度字段
        /// </summary>
        /// <param name="lines">线数据集集合</param>
        /// <param name="points">点数据集集合（可为空）</param>
        /// <param name="name">网络数据集名字</param>
        /// <param name="ToleranceTh">节点容限，单位m</param>
        /// <returns>返回网络数据集</returns>
        private DatasetVector BuildNetwork(DatasetVector[] lines, DatasetVector[] points, string name, double ToleranceTh)
        {
            try
            {
                //构建网络数据集
                DatasetVector network = NetworkBuilder.BuildNetwork(lines, points, new string[] { }, new string[] { }, m_datasource, m_datasource.Datasets.GetAvailableDatasetName(name), NetworkSplitMode.LineSplitByPointAndLine, ToleranceTh);
                //节点中添加Conn（度）字段
                FieldInfo fieldInfo = new FieldInfo()
                {
                    Name = "Conn",
                    Caption = "Conn",
                    DefaultValue = "0",
                    Type = FieldType.Int32,
                    IsRequired = true
                };
                FieldInfos fieldInfos = network.ChildDataset.FieldInfos;
                fieldInfos.Add(fieldInfo);
                //网络数据集，节点：添加字段后释放会报错
                //fieldInfos.Dispose();

                //获取网络数据集（弧段、节点）
                Recordset recordsetLine = network.GetRecordset(false, CursorType.Dynamic);
                Recordset recordsetNode = network.ChildDataset.GetRecordset(false, CursorType.Dynamic);
                recordsetNode.MoveFirst();
                //获取批量更新对象（500条更新一次）
                Recordset.BatchEditor editor = recordsetNode.Batch;
                editor.MaxRecordCount = 500;
                //开始编辑
                editor.Begin();
                //计算节点度
                for (int i = 0; i < recordsetNode.RecordCount; i++)
                {
                    int conn = 0;
                    recordsetLine.MoveFirst();
                    for (int j = 0; j < recordsetLine.RecordCount; j++)
                    {
                        if (recordsetNode.GetID() == recordsetLine.GetInt32("SmFNode"))
                        {
                            conn++;
                        }
                        if (recordsetNode.GetID() == recordsetLine.GetInt32("SmTNode"))
                        {
                            conn++;
                        }
                        //移动记录
                        recordsetLine.MoveNext();
                    }
                    //记录
                    recordsetNode.SetInt32("Conn", conn);
                    recordsetNode.MoveNext();

                }
                //提交编辑
                editor.Update();
                //释放局部资源
                recordsetNode.Dispose();
                recordsetLine.Dispose();
                //返回结果
                return network;
            }
            catch (Exception)
            {

                throw;
            }
        }
        /// <summary>
        /// 构建网络，添加节点度字段
        /// </summary>
        /// <param name="lines">线数据集集合</param>
        /// <param name="points">点数据集集合（可为空）</param>
        /// <param name="name">网络数据集名字</param>
        /// <param name="ToleranceTh">节点容限，单位m</param>
        /// <param name="Token">取消操作的对象</param>
        /// <returns>返回网络数据集</returns>
        private DatasetVector BuildNetwork(DatasetVector[] lines, DatasetVector[] points, string name, double ToleranceTh, CancellationToken Token)
        {
            try
            {
                //构建网络数据集
                DatasetVector network = NetworkBuilder.BuildNetwork(lines, points, new string[] { }, new string[] { }, m_datasource, m_datasource.Datasets.GetAvailableDatasetName(name), NetworkSplitMode.LineSplitByPointAndLine, ToleranceTh);
                //节点中添加Conn（度）字段
                FieldInfo fieldInfo = new FieldInfo()
                {
                    Name = "Conn",
                    Caption = "Conn",
                    DefaultValue = "0",
                    Type = FieldType.Int32,
                    IsRequired = true
                };
                FieldInfos fieldInfos = network.ChildDataset.FieldInfos;
                fieldInfos.Add(fieldInfo);

                //获取网络数据集（弧段、节点）
                Recordset recordsetLine = network.GetRecordset(false, CursorType.Dynamic);
                Recordset recordsetNode = network.ChildDataset.GetRecordset(false, CursorType.Dynamic);
                recordsetNode.MoveFirst();
                //获取批量更新对象（500条更新一次）
                Recordset.BatchEditor editor = recordsetNode.Batch;
                editor.MaxRecordCount = 500;
                //开始编辑
                editor.Begin();
                //计算节点度
                for (int i = 0; i < recordsetNode.RecordCount; i++)
                {
                    int conn = 0;
                    recordsetLine.MoveFirst();
                    for (int j = 0; j < recordsetLine.RecordCount; j++)
                    {
                        if (Token.IsCancellationRequested)
                        {
                            //释放局部资源
                            //fieldInfos.Dispose();
                            recordsetNode.Dispose();
                            recordsetLine.Dispose();
                            //删除临时网络数据集
                            m_datasource.Datasets.Delete(network.Name);
                            return null;
                        }
                        else
                        {
                            if (recordsetNode.GetID() == recordsetLine.GetInt32("SmFNode"))
                            {
                                conn++;
                            }
                            if (recordsetNode.GetID() == recordsetLine.GetInt32("SmTNode"))
                            {
                                conn++;
                            }
                            //移动记录
                            recordsetLine.MoveNext();
                        }
                    }
                    //记录
                    recordsetNode.SetInt32("Conn", conn);
                    recordsetNode.MoveNext();

                }
                //提交编辑
                editor.Update();
                //释放局部资源
                //fieldInfos.Dispose();
                recordsetNode.Dispose();
                recordsetLine.Dispose();
                //返回结果
                return network;
            }
            catch (Exception)
            {

                throw;
            }
        }
        /// <summary>
        /// 获取每层搜索深度的几何对象集
        /// </summary>
        /// <param name="geometry">几何对象</param>
        /// <param name="datasets">集合对象所在数据集集合</param>
        /// <param name="depth">搜索深度</param>
        /// <returns>返回几何对象集的列表</returns>
        private List<Geometry[]> GetGeoData(Geometry geometry, DatasetVector[] datasets, int depth)
        {
            try
            {
                //记录每级搜索深度得到的的几何对象数组的全队列
                List<Geometry[]> geometries = new List<Geometry[]>();
                //记录搜索对象和其id,0级是geometry自己
                List<int> ids = new List<int> { geometry.ID };
                Geometry[] geometriesDs = new Geometry[] { geometry };
                //添加到  每级搜索深度得到的的几何对象数组  队列
                geometries.Add(geometriesDs);
                //实例查询参数（查询对象(循环内添加)、查询算子、静态游标）
                QueryParameter queryParameter = new QueryParameter()
                {
                    SpatialQueryMode = SpatialQueryMode.Intersect,
                    CursorType = CursorType.Static
                };
                //循环搜索几何对象
                for (int d = 0; d < depth; d++)
                {
                    //记录本次搜索得到的对象
                    List<Geometry> geometriesDlist = new List<Geometry>();
                    for (int i = 0; i < geometriesDs.Length; i++)
                    {
                        //设置查询对象
                        queryParameter.SpatialQueryObject = geometriesDs[i];
                        for (int j = 0; j < datasets.Length; j++)
                        {
                            //查询得到记录集
                            Recordset recordset = datasets[j].Query(queryParameter);
                            if (recordset != null)
                            {
                                for (int n = 0; n < recordset.RecordCount; n++)
                                {
                                    //移动到对应记录
                                    recordset.MoveTo(n);
                                    //获取搜索得到的对象
                                    Geometry geometryDepth = recordset.GetGeometry();
                                    //判断是否已经搜索得到过了
                                    if (!ids.Contains(geometryDepth.ID))
                                    {
                                        //没有得到过则记录
                                        geometriesDlist.Add(geometryDepth);
                                        //同时记录id
                                        ids.Add(geometryDepth.ID);
                                    }
                                }
                                //释放局部资源
                                recordset.Dispose();
                            }
                        }
                    }
                    //更新搜索对象的数组
                    geometriesDs = geometriesDlist.ToArray();
                    //添加到  每级搜索深度得到的的几何对象数组  队列
                    geometries.Add(geometriesDs);
                }
                //返回结果
                return geometries;
            }
            catch (Exception)
            {

                throw;
            }
        }
        /// <summary>
        /// 获取每层几何对象集的AaC值
        /// </summary>
        /// <param name="geometries">几何对象集的列表</param>
        /// <param name="network">集合对象所在网络集</param>
        /// <returns>返回几何对象集的AaC值的列表</returns>
        private List<int[]> GetAaCinfo(List<Geometry[]> geometries, DatasetVector network)
        {
            try
            {
                //记录每层 弧段数和节点度 的累计和
                List<int[]> arcAndConns = new List<int[]>();
                //实例查询参数（查询对象(循环内添加)、查询算子、静态游标）
                QueryParameter queryParameter = new QueryParameter()
                {
                    SpatialQueryMode = SpatialQueryMode.Contain,
                    CursorType = CursorType.Static
                };
                //获取每层的对象集合（这是四种计算方式的第三种，另三种再做打算）
                foreach (Geometry[] geometrieD in geometries)
                {
                    //记录当前层的弧段数和节点度
                    int arc = 0, conn = 0;
                    for (int i = 0; i < geometrieD.Length; i++)
                    {
                        //设置查询对象
                        queryParameter.SpatialQueryObject = geometrieD[i];
                        //查询弧段记录,并记录数量
                        Recordset aocRecord = network.Query(queryParameter);
                        if (aocRecord != null)
                        {
                            arc += aocRecord.RecordCount;
                            //释放局部资源
                            aocRecord.Dispose();
                        }
                        //查询节点记录,并获取节点的度
                        Recordset nodeRecord = network.ChildDataset.Query(queryParameter);
                        if (nodeRecord != null)
                        {
                            for (int j = 0; j < nodeRecord.RecordCount; j++)
                            {
                                //移动到对应记录
                                nodeRecord.MoveTo(j);
                                //统计节点的度
                                conn += nodeRecord.GetInt32("Conn");
                            }
                            //释放局部资源
                            nodeRecord.Dispose();
                        }
                    }
                    //添加到累计和队列中
                    arcAndConns.Add(new int[] { arc, conn });
                }
                //返回结果
                return arcAndConns;
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// 根据几何对象的AaC的值，计算相似度
        /// </summary>
        /// <param name="arcAndConns1">几何对象1的AaC值列表</param>
        /// <param name="arcAndConns2">几何对象2的AaC值列表</param>
        /// <param name="topologyError">拓扑匹配结果保留阈值</param>
        /// <returns>返回拓扑相似度</returns>
        private double GetSim(List<int[]> arcAndConns1, List<int[]> arcAndConns2, double topologyError)
        {
            try
            {
                //记录总体相似度
                double sim = 1;
                //获取循环计算次数(最小值)
                int count = Math.Min(arcAndConns1.Count, arcAndConns2.Count);
                //循环计算每层对象的相似度
                for (int i = 0; i < count; i++)
                {
                    double X1 = arcAndConns1[i][0];
                    double Y1 = arcAndConns1[i][1];
                    double X2 = arcAndConns2[i][0];
                    double Y2 = arcAndConns2[i][1];

                    //计算向量夹角
                    double A = (X1 * X2 + Y1 * Y2) / (Math.Sqrt(X1 * X1 + Y1 * Y1) * Math.Sqrt(X2 * X2 + Y2 * Y2));
                    //计算弧段数所占权值
                    double Sa = 1 - Math.Abs(X1 - X2) / Math.Max(X1, X2);
                    //计算节点连通度所占权值
                    double Sc = 1 - Math.Abs(Y1 - Y2) / Math.Max(Y1, Y2);
                    //计算累计相似度
                    sim = sim * 0.5 * (Sa * A + Sc * A);
                    //如果出现无值，根据分析，深度搜索时，其返回的层数不一致导致，如：孤立线和网络中其他线的计算时。因而判定其相似结果为零
                    if (double.IsNaN(sim))
                    {
                        sim = 0.0;
                        break;
                    }
                    //小于阈值之后不继续计算了，直接跳出
                    else if (sim < topologyError)
                    {
                        break;
                    }
                }
                //返回相似度结果
                return sim;
            }
            catch (Exception)
            {

                throw;
            }
        }
    }
}
